from django.shortcuts import render
from apps.users.models import User, Address
from django.http import JsonResponse, HttpResponseBadRequest
from django.views import View
import json
import re
import logging
from django.contrib.auth import login, authenticate, logout
from django_redis import get_redis_connection
from utils.views import LoginRequiredJsonMixin
from django.conf import settings
from apps.users.utils import dumps_email_token, loads_email_token, token_cleck
from celery_tasks.emails.tasks import send_email
logger = logging.getLogger('django')

# Create your views here.

class UserPasswordUpdateView(LoginRequiredJsonMixin, View):
    def put(self, request):
        # 接受参数
        password_dict = json.loads(request.body.decode())
        old_password = password_dict.get('old_password')
        new_password = password_dict.get('new_password')
        new_password2 = password_dict.get('new_password2')

        # 效验参数
        # 校验参数
        if not all([old_password, new_password, new_password2]):
            return JsonResponse({'code': 400,
                                'errmsg': '缺少必传参数'})

        result = request.user.check_password(old_password)
        if not result:
            return JsonResponse({'code': 400,
                                'errmsg': '原始密码不正确'})

        if not re.match(r'^[0-9A-Za-z]{8,20}$', new_password):
            return JsonResponse({'code': 400,
                                'errmsg': '密码最少8位,最长20位'})

        if new_password != new_password2:
            return JsonResponse({'code': 400,
                                'errmsg': '两次输入密码不一致'})



        try:
            request.user.set_password(new_password)
            request.user.save()
        except Exception as e:
            logger.error(e)
            return HttpResponseBadRequest('失败')
        return JsonResponse({'code': 0,
                             'errmsg': 'ok'})


# ======================================================================================================

# 添加title
class UserAddressTitleView(LoginRequiredJsonMixin, View):
    def put(self, request, address_id):
        title_b = json.loads(request.body.decode())
        title = title_b.get('title')

        try:
            Address.objects.filter(id=address_id).update(title=title)
        except Address.DoesNotExist as e:
            logger.error(e)
            return HttpResponseBadRequest('添加失败')
        return JsonResponse({'code': 0,
                             'errmsg': 'ok'})


# ===============================================================================================================

# 设置默认地址
class UserAddressDefaultView(LoginRequiredJsonMixin, View):
    def put(self, request, address_id):
        try:
            User.objects.filter(id=request.user.id).update(default_address_id=address_id)
        except User.DoesNotExist as e:
            logger.error(e)
            return HttpResponseBadRequest('修改错误')
        return JsonResponse({'code': 0,
                             'errmsg': 'ok'})



# =================================================================================================================

# 地址增删改
class UserAddressModifyView(View):
    def delete(self, request, address_id):
        # 通过用户传来的address_id删除地址
        try:
            Address.objects.filter(id=address_id).delete()
        except Exception as e:
            logger.error(e)
            return HttpResponseBadRequest('删除失败')
        return JsonResponse({'code': 0,
                             'errmsg': 'ok'})

    def put(self, request, address_id):
        # 拿到修改后的数据
        json_dict = json.loads(request.body.decode())

        receiver = json_dict.get('receiver')
        province_id = json_dict.get('province_id')
        city_id = json_dict.get('city_id')
        district_id = json_dict.get('district_id')
        place = json_dict.get('place')
        mobile = json_dict.get('mobile')
        tel = json_dict.get('tel')
        email = json_dict.get('email')

        # 效验信息
        # 校验参数
        if not all([receiver, province_id, city_id, district_id, place, mobile]):
            return JsonResponse({'code': 400,
                                'errmsg': '缺少必传参数'})

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400,
                                'errmsg': '参数mobile有误'})

        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return JsonResponse({'code': 400,
                                    'errmsg': '参数tel有误'})
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return JsonResponse({'code': 400,
                                    'errmsg': '参数email有误'})
        # 用address_id查询数据库对象执行update
        try:
            address = Address.objects.filter(id=address_id)
            address.update(title=receiver,
                           receiver=receiver,
                           province=province_id,
                           city=city_id,
                           district=district_id,
                           place=place,
                           mobile=mobile,
                           tel=tel,
                           email=email
                           )
        except Address.DoesNotExist as e:
            logger.error(e)
            return HttpResponseBadRequest('修改失败')
        # 返回响应

        address = Address.objects.get(id=address_id)
        address_dict = {
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email
        }
        return JsonResponse({'code': 0,
                             'errmsg': 'ok',
                             'address': address_dict})


# ==================================================================================================

# 新增地址
class UserAddressCreateView(LoginRequiredJsonMixin, View):
    def post(self, request):
        # 接收参数
        json_dict = json.loads(request.body.decode())
        receiver = json_dict.get('receiver')
        province_id = json_dict.get('province_id')
        city_id = json_dict.get('city_id')
        district_id = json_dict.get('district_id')
        place = json_dict.get('place')
        mobile = json_dict.get('mobile')
        tel = json_dict.get('tel')
        email = json_dict.get('email')

        # 效验
        # 校验参数
        if not all([receiver, province_id, city_id, district_id, place, mobile]):
            return HttpResponseBadRequest('缺少必传参数')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return HttpResponseBadRequest('参数mobile有误')
        if tel:
            if not re.match(r'^(0[0-9]{2,3}-)?([2-9][0-9]{6,7})+(-[0-9]{1,4})?$', tel):
                return HttpResponseBadRequest('参数tel有误')
        if email:
            if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
                return HttpResponseBadRequest('参数email有误')

        # 保存数据
        try:
            address = Address.objects.create(
                user=request.user,
                title=receiver,
                receiver=receiver,
                province_id=province_id,
                city_id=city_id,
                district_id=district_id,
                place=place,
                mobile=mobile,
                tel=tel,
                email=email)
        except Exception as e:
            logger.error(e)
            return HttpResponseBadRequest('no')
        if not request.user.default_address_id:
            request.user.default_address_id = address
            request.user.save()
        address_dict = {
            "id": address.id,
            "title": address.title,
            "receiver": address.receiver,
            "province": address.province.name,
            "city": address.city.name,
            "district": address.district.name,
            "place": address.place,
            "mobile": address.mobile,
            "tel": address.tel,
            "email": address.email
        }
        return JsonResponse({'code': 0,
                             'errmsg': 'ok',
                             'address': address_dict})
# ==========================================================================================

# 展示地址
class UserAddressLookView(LoginRequiredJsonMixin, View):
    def get(self, request):
        # 获取所有的地址:
        addresses = Address.objects.filter(user=request.user,
                                           is_deleted=False)
        # 创建空的列表
        address_dict_list = []

        for address in addresses:
            address_dict = {
                "id": address.id,
                "title": address.title,
                "receiver": address.receiver,
                "province": address.province.name,
                "city": address.city.name,
                "district": address.district.name,
                "place": address.place,
                "mobile": address.mobile,
                "tel": address.tel,
                "email": address.email
            }

            if request.user.default_address_id == address.id:
                address_dict_list.insert(0, address_dict)
            else:
                address_dict_list.append(address_dict)

        default_id = request.user.default_address_id

        return JsonResponse({'code': 0,
                            'errmsg': 'ok',
                            'addresses': address_dict_list,
                            'default_address_id': default_id})


# =========================================================================================================

# 验证邮箱
class UserEmailCleckView(View):
    def put(self, requset):
        # 拿到token
        token_b = requset.GET.get('token')

        # 检查token
        token_dict = token_cleck(token_b)

        # 拿到数据
        user_id = token_dict.get('user_id')
        email = token_dict.get('email')

        # 效验数据
        try:
            user = User.objects.get(id=user_id, email=email)

        except User.DoesNotExist:
            return JsonResponse({'code': 400,
                                'errmsg': '没有这个用户'})

        # 设置激活
        try:
            user.email_active = True
            user.save()

        except Exception as e:
            logger.error(e)
            return JsonResponse({'code': 400,
                                'errmsg': '激活失败'})
        return JsonResponse({'code': 0,
                            'errmsg': 'ok'})



# ===================================================================================================
# 添加邮箱发送邮件
class UserEmailAddView(View):
    def put(self, request):
        # 拿到用户邮箱
        email_dict = json.loads(request.body.decode())
        email = email_dict.get('email')
        # 验证邮箱
        if not email:
            return JsonResponse({'code': 400,
                                'errmsg': '缺少email参数'})
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return JsonResponse({'code': 400,
                                'errmsg': '参数email有误'})
        # 存入数据库
        try:
            request.user.email = email
            request.user.save()
        except Exception as e:
            logger.error('数据保存错误:', e)

        #return JsonResponse({'code': 0,
        #                     'errmsg': 'ok'})

        # 生成验证url返回并以邮件的形式发送
        token = {
            'user_id': request.user.id,
            'email': request.user.email
        }
        # 加密
        token_b = dumps_email_token(token)

        token_url = settings.EMAIL_VERIFY_URL + '?token=' + token_b

        # 发邮件
        send_email.delay(email, token_url)

        return JsonResponse({'code': 0,
                            'errmsg': '0'})

# ============================================================================================================



# 用户中心用户数据

class UserInfoView(LoginRequiredJsonMixin, View):
    def get(self, request):

        info_data = {
            'username': request.user.username,
            'mobile': request.user.modile,
            'email': request.user.email,
            'email_active': request.user.email_active
        }

        return JsonResponse({'code': 0,
                             'errmsg': 'ok',
                             'info_data':info_data})


# 用户退出
class UserLogoutView(View):
    def delete(self, request):
        # 删掉session
        logout(request)

        # 删掉cookies中的username
        response = JsonResponse({'code': 0,
                                 'errmsg': 'ok'})
        response.delete_cookie('username')
        # 返回数据
        return response

# 用户密码登录
class UserLoginView(View):
    def post(self, requset):
        # 拿到数据
        userinfo_dict = json.loads(requset.body.decode())
        username = userinfo_dict.get('username')
        password = userinfo_dict.get('password')
        remember = userinfo_dict.get('remembered')

        # 效验数据
        if not all([username, password]):
            return JsonResponse({'code': 400,
                                 'errmsg': '参数缺失'})

        #　区分手机号和用户名
        if re.match('1[3-9]\d{9}', username):
            User.USERNAME_FIELD = 'mobile'

        # 查询用户
        user = authenticate(username=username,
                            password=password)
        if user == None:
            return JsonResponse({'code': 400,
                                 'errmsg': '用户不存在'})

        # 设置session
        login(requset, user)
        response = JsonResponse({'code': 0,
                                 'errmsg': 'ok'})

        if remember == True:
            requset.session.set_expiry(None)
        else:
            requset.session.set_expiry(0)

        # ============================================================================
        # 合并购物车
        from apps.carts.utils import carts_merge
        response = carts_merge(requset, response)

        # ==========================================================================================

        # 显示用户名
        response.set_cookie('username', user.username, max_age=3000)

        # 返回响应
        return response


# 用户注册
class UserRegisterView(View):

    def post(self, request):
        # 拿到数据
        # 完善注册
        user_info_json = request.body.decode()
        user_info_dict = json.loads(user_info_json)

        username = user_info_dict.get('username')
        password = user_info_dict.get('password')
        mobile = user_info_dict.get('mobile')
        password2 = user_info_dict.get('password2')
        sms_code = user_info_dict.get('sms_code')
        allow = user_info_dict.get('allow')
        # 拿到redis中的手机验证码

        redis_conn = get_redis_connection('code')
        sms_code_server = redis_conn.get('sms_%s' % mobile)


        # 效验数据
        if not all([username, password, password2, mobile, sms_code, allow]):
            return JsonResponse({'code': 200,
                                 'errmsg': '数据缺失'})
        if sms_code_server != None:
            sms_code_server = sms_code_server.decode()
        else:
            return JsonResponse({'code': 400,
                                 'errmsg': '验证码过期'})
        if sms_code_server != sms_code:
            return JsonResponse({'code': 400,
                                 'errmsg': '手机验正码不正确'})
        if not re.match('[a-zA-Z0-9-_]{5,20}', username):
            return JsonResponse({'code': 200,
                                 'errmsg': '用户名错误'})
        if not re.match('1[3-9]\d{9}', mobile):
            return JsonResponse({'code': 200,
                                 'errmsg': '手机号不符合要求'})
        if not re.match('[a-zA-Z0-9-_]{8,20}', password):
            return JsonResponse({'code': 200,
                                 'errmsg': '密码不符合要求'})
        if password != password2:
            return JsonResponse({'code': 200,
                                 'errmsg': '密码不一致'})
        if allow != True:
            return JsonResponse({'code': 200,
                                 'errmsg': '没有签协议'})



        # 效验后操作
        try:
            user = User.objects.create_user(username=username,
                                            password=password,
                                            modile=mobile)
        except Exception as e:
            print(e)
            return JsonResponse({'code': 200,
                                 'errmsg': '数据库执行失败'})
        login(request, user)
        return JsonResponse({'code': 0,
                                'errmsg': 'ok'})

# =====================================================================================================================
# 用户手机号重复注册

class UsernameCount(View):

    def get(self, request, username):
        '''用户是否存在'''
        # 查询用户
        user_count = User.objects.filter(username=username).count()
        # 判断用户数
        if user_count == 0:
            return JsonResponse({'code': 0,
                                 'errmsg': 'ok',
                                 'count': user_count})
        return JsonResponse({'code': 200,
                             'errmsg': '用户名重复',
                             'count': user_count})

# =====================================================================================================================

class MobileCount(View):

    def get(self, request, mobile):
        '''手机号是否重复'''
        mobile_count = User.objects.filter(modile=mobile).count()
        if mobile_count == 0:
            return JsonResponse({'code': 0,
                                 'errmsg': 'ok',
                                 'count': mobile_count})
        return JsonResponse({'code': 200,
                             'errmsg': '手机号重复',
                             'count': mobile_count})